package zhuyun.code

import org.omg.CORBA.Object

class Node<E>(var prev:Node<E>?, val element:E, var next:Node<E>?)
class LinkedList<E>(var size:Int,var first:Node<E>?,var last:Node<E>?){
    private fun rangeCheck(index:Int){
        if(index<0||index>size-1){
            throw ArrayIndexOutOfBoundsException()
        }
    }
    private fun getAt(index:Int):Node<E>?{
        rangeCheck(index)
        var node=first
        var i =  0
        while(node!=null&&i<index){
            node=node.next
            i++
        }
        return node
    }
    fun add(index:Int,element: E){
        val newNode = Node<E>(null,element,null)
        if(index == 0){
            if(size == 0){
                first = newNode
                last = first
                newNode.prev = newNode
                newNode.next = newNode
            } else {
                newNode.prev = last
                newNode.next = first
                first?.prev=newNode
                first = newNode
            }
        } else {
            val node = getAt(index-1)
            newNode.next= node!!.next
            newNode.prev=node
            node.next!!.prev=newNode
            node.next = newNode
            if(node == last){
                last = newNode
            }
        }
        size++
    }
    fun remove(index:Int):E{
        val node = getAt(index)
        if(index == 0){
            if(size == 1){
                first = null
                last = null
            }
            else {
                first= node!!.next
                first!!.prev=last
            }
        } else {
            node!!.prev!!.next=node.next
            node.next!!.prev=node.prev
            if (index == size-1){
                last = node.prev
            }
        }
        return node!!.element
    }
    fun orderPrint(){
        var node = first
        do {
            print(node!!.element.toString()+" ")
            node=node.next
        }while (node!=first)
        println()
    }
    fun reverseOrderPrint(){
        var node = last
        do {
            print(node!!.element.toString()+" ")
            node = node.prev
        }while (node!=last)
        println()
    }
}

fun main(args:Array<String>){
    val linkedList = LinkedList<String>(0,null,null)
    linkedList.add(0,"123")
    linkedList.add(1,"456")
    linkedList.add(2,"789")
    linkedList.orderPrint()
    linkedList.reverseOrderPrint()
    linkedList.remove(1)
    linkedList.orderPrint()
    linkedList.reverseOrderPrint()

}

